﻿using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AcDotNetTool;
namespace _03编辑图形
{
    public static  partial class EditEntityTool
    {
        /// <summary>
        /// 改变图形颜色
        /// </summary>
        /// <param name="c1Id">图形的ObjectId</param>
        /// <param name="colorIndex">颜色索引</param>
        public  static void ChangeEntityColor(this ObjectId c1Id, short colorIndex)
        {
            //图形数据库
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //打开块表
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                //打开块表记录
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
                //获取图形对象
                Entity ent1 = (Entity)c1Id.GetObject(OpenMode.ForWrite);
                ent1.ColorIndex = colorIndex;
                trans.Commit();
            }
        }
        /// <summary>
        /// 改变图形颜色
        /// </summary>
        /// <param name="ent">图形对象</param>
        /// <param name="colorIndex">颜色索引</param>
        public static void ChangeEntityColor(this Entity ent, short colorIndex)
        {
            //判断图形的IsNewlyObject
            if (ent.IsNewObject)
            {
                ent.ColorIndex = colorIndex;
            }
            else
            {
                ent.ObjectId.ChangeEntityColor(colorIndex);
            }
        }
        /// <summary>
        /// 移动图形
        /// </summary>
        /// <param name="entId">图形对象的ObjectId</param>
        /// <param name="sorucePoint">参考原点</param>
        /// <param name="targetPoint">参考目标点</param>
        public static void MoveEntity(this ObjectId entId, Point3d sourcePoint, Point3d targetPoint)
        {
            //当前图形数据库
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //打开块表
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                //打开块表记录
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
                //打开图形
                //Entity ent = (Entity)trans.GetObject(entId, OpenMode.ForWrite);
                Entity ent = (Entity)entId.GetObject(OpenMode.ForWrite);
                //计算变换矩阵
                Vector3d vector = sourcePoint.GetVectorTo(targetPoint);
                Matrix3d mt = Matrix3d.Displacement(vector);
                ent.TransformBy(mt);
                //提交事务处理
                trans.Commit();
            }
        }
        /// <summary>
        /// 移动图形
        /// </summary>
        /// <param name="entId">图形对象</param>
        /// <param name="sorucePoint">参考原点</param>
        /// <param name="targetPoint">参考目标点</param>
        public static void MoveEntity(this Entity ent, Point3d sourcePoint, Point3d targetPoint)
        {
            //判断图形对象的IsNewlyObejct属性
            if (ent.IsNewObject)
            {
                //计算变换矩阵
                Vector3d vector = sourcePoint.GetVectorTo(targetPoint);
                Matrix3d mt = Matrix3d.Displacement(vector);
                ent.TransformBy(mt);
            }
            else
            {
                ent.ObjectId.MoveEntity(sourcePoint, targetPoint);
            }
        }
        /// <summary>
        /// 复制图形
        /// </summary>
        /// <param name="entId">图形的半ObjectId</param>
        /// <param name="sourcePoint">参考起点</param>
        /// <param name="targetPoint">参考终点</param>
        /// <returns>图形对象,没有加入图形数据库</returns>
        public static Entity CopyEntity(this ObjectId entId, Point3d sourcePoint, Point3d targetPoint)
        {
            //声明一个图形对象
            Entity entR;
            //当前图形数据库
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //打开块表
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                //打开块表记录
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
                //打开图形
                //Entity ent = (Entity)trans.GetObject(entId, OpenMode.ForWrite);
                Entity ent = (Entity)entId.GetObject(OpenMode.ForWrite);
                
                //计算变换矩阵
                Vector3d vector = sourcePoint.GetVectorTo(targetPoint);
                Matrix3d mt = Matrix3d.Displacement(vector);
                entR =  ent.GetTransformedCopy(mt);
                //提交事务处理
                trans.Commit();
            }

            return entR;
        }
        /// <summary>
        /// 复制图形
        /// </summary>
        /// <param name="entId">图形对象ram>
        /// <param name="sourcePoint">参考起点</param>
        /// <param name="targetPoint">参考终点</param>
        /// <returns>图形对象,没有加入图形数据库</returns>
        public static Entity CopyEntity(this Entity ent, Point3d sourcePoint, Point3d targetPoint)
        {
            //声明一个图形对象
            Entity entR;
            //判断图形对象的IsNewlyObejct属性
            if (ent.IsNewObject)
            {
                //计算变换矩阵
                Vector3d vector = sourcePoint.GetVectorTo(targetPoint);
                Matrix3d mt = Matrix3d.Displacement(vector);
                entR =  ent.GetTransformedCopy(mt);
            }
            else
            {
                entR =  ent.ObjectId.CopyEntity(sourcePoint, targetPoint);
            }
            return entR;
        }
        /// <summary>
        /// 旋转图形
        /// </summary>
        /// <param name="ent">图形对象的ObjectId</param>
        /// <param name="center">旋转中点</param>
        /// <param name="degree">旋转的角度</param>
        public static void  RotateEntity(this ObjectId entId, Point3d center,double degree)
        {
            
            //当前图形数据库
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //打开块表
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                //打开块表记录
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
                //打开图形
                //Entity ent = (Entity)trans.GetObject(entId, OpenMode.ForWrite);
                Entity ent = (Entity)entId.GetObject(OpenMode.ForWrite);

                //计算变换矩阵
                Matrix3d mt = Matrix3d.Rotation(degree.DegreeToAngle(), Vector3d.ZAxis, center);
                ent.TransformBy(mt);
                //提交事务处理
                trans.Commit();
            }
        }
        /// <summary>
        /// 旋转图形
        /// </summary>
        /// <param name="ent">图形对象</param>
        /// <param name="center">旋转中点</param>
        /// <param name="degree">旋转的角度</param>
        public static void RotateEntity(this Entity ent, Point3d center, double degree)
        {
            //判断图形对象的IsNewlyObejct属性
            if (ent.IsNewObject)
            {
                //计算变换矩阵

                Matrix3d mt = Matrix3d.Rotation(degree.DegreeToAngle(), Vector3d.ZAxis, center);
                ent.TransformBy(mt);
            }
            else
            {
                ent.ObjectId.RotateEntity(center, degree);
            }
        }
        /// <summary>
        /// 镜像图形
        /// </summary>
        /// <param name="entId">图形对象的ObjectId</param>
        /// <param name="point1">第一个镜像点</param>
        /// <param name="point2">第二个镜像点</param>
        /// <param name="isEraseSoruce">是否删除原图</param>
        /// <returns>返回新的图形对象，没有加入图形数据库</returns>
        public static Entity MirrorEntity(this ObjectId entId, Point3d point1, Point3d point2, bool isEraseSoruce)
        {
            //声明一个图形对象,用于返回
            Entity entR;
            //计算镜像的变换矩阵
            Matrix3d mt = Matrix3d.Mirroring(new Line3d(point1, point2));
            //打开事务处理
            using (Transaction trans = entId.Database.TransactionManager.StartTransaction())
            {
                //打开原对象
                Entity ent = (Entity)trans.GetObject(entId, OpenMode.ForWrite);
                //这里得到的图形的IsNewlyObject = true
                entR = ent.GetTransformedCopy(mt);
                //判断是否删除对象
                if (isEraseSoruce)
                {
                    ent.Erase();
                }
                trans.Commit();
            }
            return entR;
        }
        /// <summary>
        /// 镜像图形
        /// </summary>
        /// <param name="entId">图形对象</param>
        /// <param name="point1">第一个镜像点</param>
        /// <param name="point2">第二个镜像点</param>
        /// <param name="isEraseSoruce">是否删除原图</param>
        /// <returns>返回新的图形对象，没有加入图形数据库</returns>
        public static Entity MirrorEntity(this Entity ent, Point3d point1, Point3d point2, bool isEraseSoruce)
        {
            //声明一个图形对象,用于返回
            Entity entR;
            if (ent.IsNewObject == true)
            {
                //计算镜像的变换矩阵
                Matrix3d mt = Matrix3d.Mirroring(new Line3d(point1, point2));
                entR = ent.GetTransformedCopy(mt);
            }
            else
            {
                
                entR  = ent.ObjectId.MirrorEntity(point1, point2, isEraseSoruce);
            }
            return entR;
        }
        /// <summary>
        /// 缩放图形
        /// </summary>
        /// <param name="entId">图形对象的ObjectId</param>
        /// <param name="basePoint">缩放的基点</param>
        /// <param name="facter">缩放比例</param>
        public static void ScaleEntity(this ObjectId entId, Point3d basePoint, double facter)
        {
            //计算缩放矩阵
            Matrix3d mt = Matrix3d.Scaling(facter, basePoint);
            //启动事务处理
            using (Transaction trans = entId.Database.TransactionManager.StartTransaction())
            {
                //打开要缩放的图形对象
                Entity ent = (Entity)entId.GetObject(OpenMode.ForWrite);
                ent.TransformBy(mt);
                trans.Commit();
            }
        }
        /// <summary>
        /// 缩放图形
        /// </summary>
        /// <param name="entId">图形对象的</param>
        /// <param name="basePoint">缩放的基点</param>
        /// <param name="facter">缩放比例</param>
        public static void ScaleEntity(this Entity ent, Point3d basePoint, double facter)
        {
            //判断图形对象的IsNewlyObject属性
            if (ent.IsNewObject == true)
            {
                //计算缩放矩阵
                Matrix3d mt = Matrix3d.Scaling(facter, basePoint);
                ent.TransformBy(mt);
            }
            else
            {
                ent.ObjectId.ScaleEntity(basePoint, facter);
            }
        }
        /// <summary>
        /// 删除图形对象
        /// </summary>
        /// <param name="entId">图形对象的ObjectId</param>
        public static void EraseEntity(this ObjectId entId)
        {
            //打开事务处理
            using (Transaction trans = entId.Database.TransactionManager.StartTransaction())
            {
                //打开要缩放的图形对象
                Entity ent = (Entity)entId.GetObject(OpenMode.ForWrite);
                ent.Erase();
                trans.Commit();
            }
        }
        /// <summary>
        /// 巨型阵列
        /// </summary>
        /// <param name="entId">图形对象的ObjectId</param>
        /// <param name="rowNum">行数</param>
        /// <param name="columnNum">列数</param>
        /// <param name="disRow">行距</param>
        /// <param name="disColumn">列距</param>
        /// <returns>List<Entity> 已加入图形数据库</returns>
        public static List<Entity> ArrayRectEntity(this ObjectId entId,int rowNum,int columnNum,double disRow,double disColumn)
        {
            //声明一个Enity类型的集合
            List<Entity> entList = new List<Entity>();
            //当前图形数据库
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //打开块表
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                //打开块表记录
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                //打开图形
                //Entity ent = (Entity)trans.GetObject(entId, OpenMode.ForWrite);
                Entity ent = (Entity)entId.GetObject(OpenMode.ForWrite);
                //计算变换矩阵
                for (int i = 0; i < rowNum; i++)
                {
                    for (int j = 0; j < columnNum; j++)
                    {
                        Matrix3d mt = Matrix3d.Displacement(new Vector3d(j * disColumn, i * disRow, 0));
                        Entity entA = ent.GetTransformedCopy(mt);
                        btr.AppendEntity(entA);
                        trans.AddNewlyCreatedDBObject(entA,true);
                        entList.Add(entA);
                    }
                }
                ent.Erase();
                //提交事务处理
                trans.Commit();

            }
            return entList;
        }
        /// <summary>
        /// 巨型阵列
        /// </summary>
        /// <param name="entId">图形对象</param>
        /// <param name="rowNum">行数</param>
        /// <param name="columnNum">列数</param>
        /// <param name="disRow">行距</param>
        /// <param name="disColumn">列距</param>
        /// <returns>List<Entity> 已加入图形数据库</returns>
        public static List<Entity> ArrayRectEntity(this Entity entS, int rowNum, int columnNum, double disRow, double disColumn)
        {
            if (entS.IsNewObject == true)
            {
                //声明一个Enity类型的集合
                List<Entity> entList = new List<Entity>();
                Database db = HostApplicationServices.WorkingDatabase;
                using (Transaction trans = db.TransactionManager.StartTransaction())
                {
                    //打开块表
                    BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                    //打开块表记录
                    BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                    for (int i = 0; i < rowNum; i++)
                    {
                        for (int j = 0; j < columnNum; j++)
                        {
                            Matrix3d mt = Matrix3d.Displacement(new Vector3d(j * disColumn, i * disRow, 0));
                            Entity entA = entS.GetTransformedCopy(mt);
                            btr.AppendEntity(entA);
                            trans.AddNewlyCreatedDBObject(entA, true);
                            entList.Add(entA);
                        }
                    }
                    trans.Commit();
                }
                return entList; 
            }
            else
            {
               return entS.ArrayRectEntity(rowNum, columnNum, disRow, disColumn);
            }
        }

        public static List<Entity> ArrayPolarEntity(this ObjectId entId, int num, double degree,Point3d center)
        {
            //声明一个List集合,用于返回
            List<Entity> entList = new List<Entity>();
            //打开事务处理
            using (Transaction trans = entId.Database.TransactionManager.StartTransaction())
            {
                //打开块表
                BlockTable bt = (BlockTable)trans.GetObject(entId.Database.BlockTableId, OpenMode.ForRead);
                //打开块表记录
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                Entity ent = (Entity)entId.GetObject(OpenMode.ForWrite);
                //限定阵列角度的大小
                degree = degree > 360 ? 360 : degree;
                degree = degree < -360 ? -360 : degree;
                int divAngNum = num-1;
                if (degree == 360 || degree == -360)
                {
                    divAngNum = num;
                }
                for (int i = 0; i < num; i++)
                {
                    Matrix3d mt = Matrix3d.Rotation((i * degree / divAngNum).DegreeToAngle(), Vector3d.ZAxis, center);
                    Entity entA = ent.GetTransformedCopy(mt);
                    btr.AppendEntity(entA);
                    trans.AddNewlyCreatedDBObject(entA, true);
                    entList.Add(entA);
                }
                ent.Erase();
                trans.Commit();
            }
            return entList;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ent"></param>
        /// <param name="num"></param>
        /// <param name="degree"></param>
        /// <param name="center"></param>
        /// <returns></returns>
        public static List<Entity> ArrayPolarEntity(this Entity ent, int num, double degree, Point3d center)
        {
            if (ent.IsNewObject == true)
            {
                //声明一个List集合,用于返回
                List<Entity> entList = new List<Entity>();
                Database db = HostApplicationServices.WorkingDatabase;
                using (Transaction trans = db.TransactionManager.StartTransaction())
                {
                    //打开块表
                    BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                    //打开块表记录
                    BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                    degree = degree > 360 ? 360 : degree;
                    degree = degree < -360 ? -360 : degree;
                    int divAngNum = num - 1;
                    if (degree == 360 || degree == -360)
                    {
                        divAngNum = num;
                    }
                    for (int i = 0; i < num; i++)
                    {
                        Matrix3d mt = Matrix3d.Rotation((i * degree / divAngNum).DegreeToAngle(), Vector3d.ZAxis, center);
                        Entity entA = ent.GetTransformedCopy(mt);
                        btr.AppendEntity(entA);
                        trans.AddNewlyCreatedDBObject(entA, true);
                        entList.Add(entA);
                    }
                    trans.Commit();
                }
                return entList;
            }
            else
            {
               return ent.ObjectId.ArrayPolarEntity(num, degree, center);
            }
        }
    }
}
